#ifndef __VALIDATOR_H
#define __VALIDATOR_H

#include "value.h"

typedef enum {
    CCONF_VALIDATE_ERROR_NO_ERROR = 0,
    CCONF_VALIDATE_ERROR_TYPE,
    CCONF_VALIDATE_ERROR_NUMRANGE,
    CCONF_VALIDATE_ERROR_RANGE,
    CCONF_VALIDATE_ERROR_USR
} cconf_validate_error_t;

typedef int (*cconf_validate_fcn_t)(char ** err, char * value, void * arg);

typedef struct cconf_validator_s {
    cconf_validate_fcn_t validate_fcn;
    char (*error_str_fcn)(int);
    void (*arg_free_fcn)(void * arg);
    void * arg;
    char * docstring;
} cconf_validator_t;

char ** str_to_list(char * str, char * delim);
void strlist_free(char ** arg);

char * cconf_validate_error_str(cconf_validator_t * v, cconf_validate_error_t error);

cconf_validator_t * cconf_validator_new_user(cconf_validate_fcn_t fcn, void * arg, char * docstring);
cconf_validator_t * cconf_validator_new_string(void);

cconf_validator_t * cconf_validator_new_strlist(char * list);
cconf_validator_t * cconf_validator_new_strset(char * set);

cconf_validator_t * cconf_validator_new_doublerange(double low, double hi);
cconf_validator_t * cconf_validator_new_double(void);
cconf_validator_t * cconf_validator_new_intrange(int low, int hi);
cconf_validator_t * cconf_validator_new_int(void);

int cconf_validator_validate(cconf_validator_t * v, char ** err, char * value);

void cconf_validator_free(cconf_validator_t * v);

#endif

